package com.five.matebook.activity;

import android.Manifest;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.AdapterView;
import android.widget.PopupMenu;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.five.matebook.R;
import com.five.matebook.activity.columeedit.CustomEditActivity;
import com.five.matebook.activity.columeedit.CustomValueManager;
import com.five.matebook.activity.config.ConfigDataBean;
import com.five.matebook.activity.config.StroageConfig;
import com.five.matebook.activity.db.IncomeRecordTable;
import com.five.matebook.activity.db.OneQueryData;
import com.five.matebook.activity.db.QueryFilter;
import com.five.matebook.activity.db.OutcomeRecordTable;
import com.five.matebook.activity.income.IncomeLsitFragment;
import com.five.matebook.activity.income.IncomeRecordActivity;
import com.five.matebook.activity.matebook.MateBookManager;
import com.five.matebook.activity.matebook.Matebook;
import com.five.matebook.activity.outcome.OutcomeColume;
import com.five.matebook.activity.outcome.OutcomeListFragment;
import com.five.matebook.activity.outcome.OutcomeRecordActivity;
import com.five.matebook.activity.sync.DbUploader;
import com.five.matebook.utils.DateUtils;
import com.five.matebook.utils.DeviceUtils;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends BaseRecordActivity implements DbUploader.ICallback {
    private static final String TAG = "MainActivity";
    private ViewPager mPager;
    private FragmentPagerAdapter mAdatper;
    private List<Fragment> mFragmentList = new ArrayList<>();

    private List<ViewGroup> mTabViewList = new ArrayList<>();

    private TextView txtOverView;
    private TextView txtLastDbSyncTime;

    private Spinner spinnerMatebook;

    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // 先判断有没有权限
            if (Environment.isExternalStorageManager()) {
            } else {
                Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, 10086);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 先判断有没有权限
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10086);
            }
        }
    }


    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestPermission();

        final MateBookManager mateBookManager = StroageConfig.get(this).getMateBookManager();

        ConfigDataBean config = StroageConfig.get(this);

        // 数据库还创建/同步下来
        if (!mateBookManager.hasMatebook()) {
            Intent it = new Intent(this, DbInitActivity.class);
            startActivity(it);
            this.finish();
            return;
        }

        setContentView(R.layout.activity_main);
        this.spinnerMatebook = findViewById(R.id.spinner_matebook);
        this.txtOverView = findViewById(R.id.txt_overView);
        this.txtLastDbSyncTime = findViewById(R.id.txt_db_sync_time);

        {
            mTabViewList.add(findViewById(R.id.tab_outcome));
            mTabViewList.add(findViewById(R.id.tab_income));
            {
                for (ViewGroup tab : mTabViewList) {
                    tab.setOnLongClickListener(new View.OnLongClickListener() {
                        @Override
                        public boolean onLongClick(View v) {
                            Object tag = tab.getTag();
                            PopupMenu popupMenu = null;
                            if (tag == null) {
                                popupMenu = new PopupMenu(MainActivity.this, v, Gravity.CENTER);
                                tab.setTag(popupMenu);
                                popupMenu.getMenu().add(Menu.NONE, Menu.FIRST, Menu.NONE, "编辑用途");
                                popupMenu.getMenu().add(Menu.NONE, Menu.FIRST + 1, Menu.NONE, "编辑对象");
                                final boolean isoutcome = v.getId() == R.id.tab_outcome;
                                if (isoutcome) {
                                    popupMenu.getMenu().add(Menu.NONE, Menu.FIRST + 2, Menu.NONE, "编辑项目");
                                }
                                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                                    @Override
                                    public boolean onMenuItemClick(MenuItem item) {
                                        Intent intent = new Intent(MainActivity.this, CustomEditActivity.class);
                                        String filed = "";
                                        int level = 0;
                                        int resId = 0;
                                        switch (item.getItemId()) {
                                            case Menu.FIRST:
                                                // 用途
                                                filed = isoutcome ? CustomValueManager.FILED_USAGE_OUTCOME : CustomValueManager.FILED_USAGE_INCOME;
                                                resId = isoutcome ? R.array.usageListMain : R.array.incomeUsageList;
                                                level = 2;
                                                break;
                                            case Menu.FIRST + 1:
                                                // 对象
                                                filed = isoutcome ? CustomValueManager.FILED_ROLE_OUTCOME : CustomValueManager.FILED_ROLE_INCOME;
                                                resId = isoutcome ? R.array.spentRole : R.array.spentRole;
                                                level = 1;
                                                break;
                                            case Menu.FIRST + 2:
                                                // 项目
                                                filed = isoutcome ? CustomValueManager.FILED_PROJECT_OUTCOME : CustomValueManager.FILED_PROJECT_INCOME;
                                                resId = isoutcome ? R.array.projectTypeList : R.array.projectTypeList;
                                                level = 1;
                                                break;
                                            default:
                                                return false;
                                        }
                                        intent.putExtra("filed", filed);
                                        intent.putExtra("resId", resId);
                                        intent.putExtra("level", level);
                                        startActivity(intent);
                                        return true;
                                    }
                                });
                            }
                            popupMenu = (PopupMenu) tab.getTag();
                            popupMenu.show();
                            return true;
                        }
                    });
                }
            }
        }
        this.mPager = findViewById(R.id.id_viewpager);
        mFragmentList.add(new OutcomeListFragment(null));
        mFragmentList.add(new IncomeLsitFragment(null));
        mAdatper = new FragmentPagerAdapter(getSupportFragmentManager()) {
            @NonNull
            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }

            @Override
            public int getCount() {
                return mFragmentList.size();
            }
        };
        mPager.setAdapter(mAdatper);
        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                setSelectedTab(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        setSelectedTab(0);

        {
            List<String> matebookList = mateBookManager.getMatebookNameList();
            if (!config.isAdmin()) matebookList.add("新建");
            spinnerMatebook.setAdapter(generateSpinnerAdapter(matebookList));
            spinnerMatebook.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    Matebook m = mateBookManager.get(position);
                    Matebook now = mateBookManager.getNowChoosed();
                    if (m == null) {
                        // add new
                        NewMatebookDialogFragment f = new NewMatebookDialogFragment(new NewMatebookDialogFragment.DialogListener() {
                            @Override
                            public void onTextEntered(String text) {
                                if (!TextUtils.isEmpty(text)) {
                                    Matebook newMatebook = mateBookManager.addMatebook(DeviceUtils.getDeviceUuid(), text);
                                    if (newMatebook == null) {
                                        showAlert("添加matebook失败");
                                    } else {
                                        mateBookManager.chooseMatebook(MainActivity.this, newMatebook);
                                        Intent it = new Intent(MainActivity.this, MainActivity.class);
                                        startActivity(it);
                                        MainActivity.this.finish();
                                    }
                                } else {
                                    setSpinnerText(spinnerMatebook, mateBookManager.getNowChoosedIndex());
                                }
                            }
                        });
                        f.show(getSupportFragmentManager(), null);
                    } else {
                        // change
                        if (m.equals(now)) {
                            // 没有改变
                        } else {
                            mateBookManager.chooseMatebook(getApplicationContext(), m);
                            Intent it = new Intent(MainActivity.this, MainActivity.class);
                            startActivity(it);
                            MainActivity.this.finish();
                        }
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {

                }
            });
            setSpinnerText(spinnerMatebook, mateBookManager.getNowChoosedIndex());
        }

        {
            spinnerMatebook.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    config.toggleAdmin();
                    StroageConfig.save(getApplicationContext());
                    Intent it = new Intent(MainActivity.this, DbInitActivity.class);
                    it.setAction(DbInitActivity.ACTION_AUTOSYNC);
                    startActivity(it);
                    MainActivity.this.finish();
                    return true;
                }
            });
        }
        if (config.isAdmin()) {
            Toast.makeText(this, "您是管理员", Toast.LENGTH_SHORT).show();
            View v = findViewById(R.id.img_add);
            v.setVisibility(View.GONE);
        }

        View syncTxt = findViewById(R.id.txt_db_sync_time);
        syncTxt.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                new AlertDialog.Builder(MainActivity.this)
                        .setMessage("是否要备份数据库文件")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                boolean ret = mateBookManager.backup(MainActivity.this);
                                Toast.makeText(MainActivity.this, ret ? "已备份" : "备份失败咯，请检查写权限", Toast.LENGTH_SHORT).show();
                            }
                        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {

                            }
                        }).show();
                return true;
            }
        });
    }

    @Override
    protected void updateChildUi() {

    }

    private void updateOverView() {
        // 上次同步的时间
        {
            long sync = StroageConfig.get(this).getLastSyncTime();
            int pendingCount = StroageConfig.get(this).getMateBookManager().getUpdateCount();
            if (pendingCount == 0) {
                if (sync == 0) {
                    this.txtLastDbSyncTime.setText("");
                } else {
                    this.txtLastDbSyncTime.setText(String.format("上一次同步时间: %s", DateUtils.toString(sync)));
                }
            } else {
                if (sync == 0) {
                    this.txtLastDbSyncTime.setText(String.format("%d条数据未同步到服务器...", pendingCount));
                } else {
                    this.txtLastDbSyncTime.setText(String.format("上一次同步时间: %s  (%d条数据未同步到服务器)", DateUtils.toString(sync), pendingCount));
                }
            }

        }

        SpannableString spannableString = new SpannableString("");

        // 统计本月支出
        QueryFilter queryFilter = new QueryFilter.Builder()
                .addLongRange(OutcomeColume.HAPPEND_TIME, DateUtils.getNowMonthBegin(), DateUtils.getNowMonthEnd())
                .sumbColume(OutcomeColume.SPENT_MONEY, "totalMoney").build();
        List<OneQueryData> data = OutcomeRecordTable.getInstance(this).query(queryFilter);
        float spent = 0;
        if (data.size() > 0) {
            spent = data.get(0).getFloat("totalMoney", 0);
        }

        // 统计本月收入
        data = IncomeRecordTable.getInstance(this).query(queryFilter);
        float income = 0;
        if (data.size() > 0) {
            income = data.get(0).getFloat("totalMoney", 0);
        }

        float sum = income - spent;
        String sumInfo = sum > 0 ? "+" + sum : String.valueOf(sum);

        String s = String.format(String.format("本月小结: %s\n本月总支出: -%s\n本月总收入: +%s\n", sumInfo, spent, income));
        SpannableString spannableString1 = new SpannableString(s);
        int start = 6;
        int end = start + sumInfo.length();
        spannableString1.setSpan(new ForegroundColorSpan(Color.parseColor("#99CCFF")), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        {
            start = end + 8;
            end = start + String.valueOf(spent).length() + 1;
        }
        spannableString1.setSpan(new ForegroundColorSpan(Color.parseColor("#ff0000")), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        {
            start = end + 8;
            end = start + String.valueOf(income).length() + 1;
        }
        spannableString1.setSpan(new ForegroundColorSpan(Color.parseColor("#00ff00")), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

        this.txtOverView.setText(spannableString1);
    }

    @Override
    protected void onResume() {
        super.onResume();
        updateOverView();
    }

    private DbUploader dbUploader = new DbUploader(this, this);
    private void tryPushDb2Server(final boolean showProgressBar, boolean forcePush) {
        synchronized (this) {
            Log.d(TAG, "try sync db file now! forcePush=" + forcePush);
            boolean ret = dbUploader.startUpload(showProgressBar, forcePush);
            if (!ret && showProgressBar) {
                showAlert("同步任务正在后台运行，请稍后重试");
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
        StroageConfig.save(this);
        if (StroageConfig.get(this).needPush2Server()) {
            tryPushDb2Server(false, false);
        } else {
            Log.d(TAG, "no need push to server");
        }
    }

    private void setSelectedTab(int index) {
        for (int i = 0; i < mTabViewList.size(); i++) {
            mTabViewList.get(i).setSelected(i == index);
        }
    }

    public void onTabClick(View v) {
        mPager.setCurrentItem(mTabViewList.indexOf(v), true);
    }

    public void onAddClick(View v) {
        // 创建旋转动画
        ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat(v, "rotation", 0f, 360f);
        rotationAnimator.setDuration(150); // 设置动画持续时间，单位为毫秒
        rotationAnimator.setInterpolator(new LinearInterpolator()); // 设置插值器，这里使用线性插值器，即匀速旋转
        v.setPivotX(v.getWidth() / 2f);
        v.setPivotY(v.getHeight() / 2f);
        rotationAnimator.start();
        rotationAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                int item = mPager.getCurrentItem();
                int id = mTabViewList.get(item).getId();
                Intent intent = null;
                switch (id) {
                    case R.id.tab_outcome:
                        intent = new Intent(MainActivity.this, OutcomeRecordActivity.class);
                        startActivity(intent);
                        break;
                    case R.id.tab_income:
                        intent = new Intent(MainActivity.this, IncomeRecordActivity.class);
                        startActivity(intent);
                        break;
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }

    public void onClick_doSync(View v) {
        if (!StroageConfig.get(this).getMateBookManager().hasUpdate()) {
            new AlertDialog.Builder(this)
                    .setTitle("提示")
                    .setMessage("没有修改，不需要同步到服务器")
                    .setCancelable(false)
                    .setPositiveButton("坚持同步", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            new AlertDialog.Builder(MainActivity.this)
                                    .setTitle("再次确认")
                                    .setMessage("是否确定要同步？")
                                    .setCancelable(false)
                                    .setPositiveButton("确认同步", new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialogInterface, int i) {
                                            tryPushDb2Server(true, true);
                                        }
                                    }).setNegativeButton("算了", null)
                                    .show();
                        }
                    })
                    .setNegativeButton("算了", null)
                    .show();
        } else {
            tryPushDb2Server(true, false);
        }
    }

    public void onClick_goQuery(View v) {
        int item = mPager.getCurrentItem();
        int id = mTabViewList.get(item).getId();
        Intent intent = null;
        switch (id) {
            case R.id.tab_outcome:
                intent = new Intent(MainActivity.this, QueryActivityOutcome.class);
                startActivity(intent);
                break;
            case R.id.tab_income:
                intent = new Intent(MainActivity.this, QueryActivityIncome.class);
                startActivity(intent);
                break;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        StroageConfig.save(getApplicationContext());
        Log.d(TAG, "onStop()");
    }

    @Override
    public void onUploadResult(boolean ret) {
        if (ret) {
            updateOverView();
        }
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }
}
